import { LoggerScheme } from "./LoggerScheme";
import { LoggerSchemes } from "./LoggerSchemes";

export class LogStackFrame {
    private data: string;
    private scheme: LoggerScheme;

    constructor(data: string, scheme?: LoggerScheme) {
        this.data = data;
        this.scheme = scheme ?? LoggerSchemes.log;
    }

    /**
     * @description: 获取日志栈帧的级别，一般用于 `LogCollection.filter()` 的回调函数进行判断。建议通过 `LogLevel` 枚举类型来比较等级。
     * @return {number} 日志栈帧的级别。
     * @example
     * ```typescript
     * // 获取日志堆栈中全部的 log 等级的日志记录
     * let collection = logStack.filter((frame) => {
     *     return frame.getLevel() == LogLevel.log;
     * });
     * ```
     */
    public getLevel(): number {
        return this.scheme.level;
    }

    /**
     * @description: 获取日志栈帧曾经输出的信息，一般用于 `LogCollection.filter()` 的回调函数进行判断。
     * @return {string} 日志栈帧曾经输出的信息。
     * @example
     * ```typescript
     * // 获取日志堆栈中全部包含其中 hello 的日志记录
     * let collection = logStack.filter((frame) => {
     *     return /hello/.test(frame.getData());
     * });
     * ```
     */
    public getData(): string {
        return this.data
    }

    /**
     * @description: 将日志堆栈的栈帧转换为字符串。
     * @return {string} 转换后的栈帧。
     */
    public toString(): string {
        return this.data;
    }

    /**
     * @description: 将日志堆栈的栈帧转换为 html 字符串用于发送日志。
     * @return {string} 转换后的栈帧。
     */
    public toHtmlString(): string {
        let htmlArray: string[] = [];
        let startTag: string = `<span style='color: ${this.scheme.color};'>`;
        let endTag: string = `</span></br>`

        for (let line of this.data.split('\n')) {
            // 转义特殊字符
            line = line.replace(/[<>&"'`\/]/g, (c) => {
                return {
                    '<': '&lt;',
                    '>': '&gt;',
                    '&': '&amp;',
                    '"': '&quot;',
                    '\'': '&#39;',
                    '`': '&#96',
                    '\/': '&#x2F'
                }[c]!;
            });
            htmlArray.push(
                [startTag, line, endTag].join('')
            );
        }

        return htmlArray.join('\n');
    }
}
